package ${packageName}.core.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;

/**
 * 
 * 数据库连接池配置类
 * 
 * @author 00fly
 * @version [版本号, ${date?date}]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Configuration
public class DruidConfig
{
    private Logger logger = LoggerFactory.getLogger(getClass());
    
    @Value("${r'${spring.datasource.url}'}")
    private String dbUrl;
    
    @Value("${r'${spring.datasource.username}'}")
    private String username;
    
    @Value("${r'${spring.datasource.password}'}")
    private String password;
    
    @Value("${r'${spring.datasource.driverClassName}'}")
    private String driverClassName;
    
    @Value("${r'${spring.datasource.initialSize}'}")
    private int initialSize;
    
    @Value("${r'${spring.datasource.minIdle}'}")
    private int minIdle;
    
    @Value("${r'${spring.datasource.maxActive}'}")
    private int maxActive;
    
    @Value("${r'${spring.datasource.maxWait}'}")
    private int maxWait;
    
    @Value("${r'${spring.datasource.timeBetweenEvictionRunsMillis}'}")
    private int timeBetweenEvictionRunsMillis;
    
    @Value("${r'${spring.datasource.minEvictableIdleTimeMillis}'}")
    private int minEvictableIdleTimeMillis;
    
    @Value("${r'${spring.datasource.validationQuery}'}")
    private String validationQuery;
    
    @Value("${r'${spring.datasource.testWhileIdle}'}")
    private boolean testWhileIdle;
    
    @Value("${r'${spring.datasource.testOnBorrow}'}")
    private boolean testOnBorrow;
    
    @Value("${r'${spring.datasource.testOnReturn}'}")
    private boolean testOnReturn;
    
    @Value("${r'${spring.datasource.poolPreparedStatements}'}")
    private boolean poolPreparedStatements;
    
    @Value("${r'${spring.datasource.filters}'}")
    private String filters;
    
    @Bean
    public ServletRegistrationBean<StatViewServlet> druidServlet()
    {
        
        ServletRegistrationBean<StatViewServlet> reg = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
        // 白名单：
        reg.addInitParameter("allow", "127.0.0.1");
        // IP黑名单 (存在共同时，deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page.
        // reg.addInitParameter("deny","192.168.1.73");
        reg.addInitParameter("loginUsername", "druid");
        reg.addInitParameter("loginPassword", "htzhE409");
        // 是否能够重置数据.
        reg.addInitParameter("resetEnable", "false");
        return reg;
    }
    
    @Bean
    public FilterRegistrationBean<WebStatFilter> filterRegistrationBean()
    {
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        filterRegistrationBean.addInitParameter("profileEnable", "true");
        filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
        filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
        return filterRegistrationBean;
    }
    
    /**
     * 数据源
     * 
     * @return 系统的数据源
     */
    @Bean
    @Primary
    public DataSource druidDataSource()
    {
        DruidDataSource datasource = new DruidDataSource();
        
        datasource.setUrl(this.dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        try
        {
            datasource.setFilters(filters);
        }
        catch (SQLException e)
        {
            logger.error("druid configuration initialization filter", e);
        }
        return datasource;
    }
    
}
